﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

static public class TimeClass
{
    public struct TimeType
    {
        public Byte Hour;
        public Byte Minute;
        public Byte Second;

        public UInt16 Year;
        public Byte Month;
        public Byte Day;
    }
    public enum WeekType
    {
        Sunday = 0,
        Monday = 1,
        Tuesday = 2,
        Wednesday = 3,
        Thursday = 4,
        Friday = 5,
        Saturday = 6,
    }

    public static Byte[] MonthTable = new byte[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    public static Byte[] WeekTable = new byte[] { 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 };
    static Boolean IsLeapYear(UInt16 year)
    {
        return (year % 100 == 0 && year % 400 == 0) || (year % 100 != 0 && year % 4 == 0);
    }

    public static Boolean JudgingLegitimacyTime(TimeType t)  //判断时间合法性
    {
        if (t.Year > 2100 || t.Year < 1970) return false;
        if (t.Month > 12 || t.Month < 1) return false;
        if (t.Month == 1 || t.Month == 3 || t.Month == 5 || t.Month == 7 || t.Month == 9 || t.Month == 10 || t.Month == 12)
        {
            if (t.Day > 31 || t.Day < 1) return false;
        }
        else if (t.Month == 2)
        {
            if (IsLeapYear(t.Year) && (t.Day > 29 || t.Day < 1)) return false;
            else { if (t.Day > 28 || t.Day < 1) return false; }
        }
        else
        {
            if (t.Day > 30 || t.Day < 1) return false;
        }
        if (t.Hour > 23 || t.Minute > 59 || t.Second > 59) return false;
        return true;
    }

    public static UInt32 TimeConvertTimeStamp(TimeType t)//获取当前时间戳
    {
        UInt32 second = 0;
        if (JudgingLegitimacyTime(t) == false)
        {
            return 0;
        }
        for (UInt16 i = 1970; i < t.Year; i++)  //
        {
            if (IsLeapYear(i)) second += 31622400;
            else second += 31536000;
        }
        for (Byte i = 0; i < t.Month - 1; i++)
        {
            second += (UInt32)MonthTable[i] * 86400;
            if (IsLeapYear(t.Year) && i == 1) second += 86400;
        }
        second += (UInt32)(t.Day - 1) * 86400;//
        second += (UInt32)t.Hour * 3600;
        second += (UInt32)t.Minute * 60;
        second += t.Second;//
        return second;
    }

    public static TimeType TimeStampConvertTime(UInt32 second)  //通过时间戳获取时间
    {
        TimeType time = new TimeType();
        UInt16 years = 0;
        UInt32 days = second / 86400;
        if (days > 0)
        {
            years = 1970;   //
            while (days >= 365)
            {
                if (IsLeapYear(years))//
                {
                    if (days >= 366) days -= 366;//
                    else { years++; break; }
                }
                else days -= 365;     //
                years++;
            }
            time.Year = years;//
            Byte months = 0;
            while (days >= 28)//
            {
                if (IsLeapYear(time.Year) && months == 1)
                {
                    if (days >= 29) days -= 29;
                    else break;
                }
                else
                {
                    if (days >= MonthTable[months]) days -= MonthTable[months];
                    else break;
                }
                months++;
            }
            time.Month = (Byte)(months + 1);
            time.Day = (Byte)(days + 1);
        }
        UInt32 seconds = second % 86400;
        time.Hour = (Byte)(seconds / 3600);
        time.Minute = (Byte)((seconds % 3600) / 60);
        time.Second = (Byte)((seconds % 3600) % 60);
        return time;
    }

    static WeekType GetWeek(TimeType[] date)
    {
        TimeType[] t = date;
        if (t[0].Month < 3)
        {
            t[0].Month += 12;
            t[0].Year--;
        }
        return (WeekType)((t[0].Day + 2 * t[0].Month + 3 * (t[0].Month + 1) / 5 + t[0].Year + t[0].Year / 4 - t[0].Year / 100 + t[0].Year / 400 + 1) % 7);
    }
    static public Byte Compare(TimeType time1, TimeType time2)
    {
        UInt32 timeStamp1 = TimeConvertTimeStamp(time1);
        UInt32 timeStamp2 = TimeConvertTimeStamp(time2);
        if (timeStamp1 == timeStamp2) return 0;  //相等返回0
        else if (timeStamp1 > timeStamp2) return 1;//时间1大返回1
        else return 2; //时间2大返回2
    }
}